#include "gtest/gtest.h"
#include <iostream>

#include "ITable.h"
namespace helper {
namespace demo {

class TableIterator : public Iterator<int, int> {
public:
  using key_type = int;
  using value_type = int;
  using pair_type = std::pair<const key_type &, const value_type &>;

  TableIterator(const key_type & start, const key_type & end)
    : start_(start), end_(end){
  }
  ~TableIterator() override {}

  pair_type current() const override {
    return pair_type(start_, 1);
  };

  void next() override {
    ++start_;
  }
  bool hasNext() const override {
    return start_ < end_;
  }
private:
  key_type start_;
  key_type end_;
};

class Table : public ITable<int, int> {
public:
  ~Table() override {}

  using super = ITable<int, int>;
  using key_type = super::key_type;
  using value_type = super::value_type;
  using visitor = super::visitor;
  using iterator = super::iterator;


  Status put(const key_type & key, const value_type & value) override {
    return Status();
  }
  Status get(const key_type & key, std::string & value) const override {
    return Status();
  }
  Status del(const key_type & key) override {
    return Status();
  }
  bool foreach(const visitor & v, const key_type & start, const key_type & end) const override {
    return true;
  }
  iterator * range(const key_type& start, const key_type& end) const override{
    return new TableIterator(start, end);
  }

  Status put(const WriteOptions & write, const key_type & key, const value_type & value) override {
    return Status();
  }
  Status get(const ReadOptions & read, const key_type & key, std::string & value) const override {
    return Status();
  }
  Status del(const WriteOptions & write, const key_type & key) override {
    return Status();
  }
  bool foreach(const ReadOptions& read, const visitor & v, const key_type& start, const key_type & end) const override {
    return true;
  }

  iterator * range(const ReadOptions & read, const key_type& start, const key_type& end) const override{
    return new TableIterator(start, end);
  }
};

}//namespace demo
}//namespace helper


TEST(TableIterator, test){ 
  using ::helper::demo::Table;
  Table tab;
  std::unique_ptr<Table::iterator> iter(tab.range(1, 10));
  for( ;iter->hasNext(); iter->next()){
    auto &&[k, v] = iter->current();
    std::cout << k << ":" << v << std::endl;
  }
}
